package avicit.bdp.dms.tdm.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.CheckParaUtils;
import avicit.bdp.dms.tdm.dao.AssetApplyDao;
import avicit.bdp.dms.tdm.dto.AssetApplyDTO;
import avicit.bdp.dms.tdm.dto.BdpAssetDTO;
import avicit.bdp.dms.tdm.dto.ProcessApproveDTO;
import avicit.bdp.dms.tdm.utils.CheckerStatus;
import avicit.bdp.dms.tdm.utils.FlowType;
import avicit.bdp.dms.tdm.utils.SysOrgUtils;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.api.sysuser.dto.SysOrg;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.commons.utils.PojoUtil;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.exception.DaoException;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryRespBean;
import avicit.platform6.modules.system.syslog.service.SysLogUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @金航数码科技有限责任公司
 * @作者：${tableInfo.classCreator}
 * @邮箱：${tableInfo.classMailbox}
 * @创建时间： 2023-11-14 16:03
 * @类说明：bdp_asset_applyService
 * @修改记录：
 */
@Service
public class AssetApplyService extends BaseService<AssetApplyDao, AssetApplyDTO> {

    private static final Logger logger = LoggerFactory.getLogger(AssetApplyService.class);

    @Autowired
    private AssetApplyDao assetApplyDao;
    @Autowired
    private BdpAssetService bdpAssetService;
    @Autowired
    private ProcessApproveService processApproveService;
    @Autowired
    private SysOrgUtils sysOrgUtils;
    @Autowired
    private ConvertColumnClient convertColumnClient;

    /**
     * 分页查询资产申请
     *
     * @param pageNo
     * @param pageSize
     * @return
     * @throws Exception
     */
    public QueryRespBean<AssetApplyDTO> getApplyPageList(String assetId, Integer pageNo, Integer pageSize)
            throws Exception {
        QueryRespBean<AssetApplyDTO> queryRespBean = new QueryRespBean<>();
        //文档密级
        String wordSecret = ThreadContextHelper.getWordSecret();

        PageHelper.startPage(pageNo, pageSize);
        Page<AssetApplyDTO> pageList = assetApplyDao.getApplyPageList(assetId, wordSecret);
        valueConvert(pageList.getResult());
        queryRespBean.setResult(pageList);
        BdpLogUtil.log4Query(queryRespBean);
        return queryRespBean;
    }

    /**
     * 通过平台API将字段值转换为名称，包括通用选择组件、通用代码
     *
     * @param assetApplyList
     */
    private void valueConvert(List<AssetApplyDTO> assetApplyList) {
        //循环组装请求数据
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (AssetApplyDTO assetApply : assetApplyList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, assetApply.getApplyPerson());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (AssetApplyDTO assetApply : assetApplyList) {
                assetApply.setCheckerStatusName(CheckerStatus.getDescByCode(assetApply.getCheckerStatus()));
                assetApply.setApplyPersonName(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, assetApply.getApplyPerson()));

                //申请单位—>根据申请人查询数据
                if (StringUtils.isNotEmpty(assetApply.getApplyPerson())) {
                    assetApply.setApplyUnit(sysOrgUtils.getOrgByUserId(assetApply.getApplyPerson()).getOrgName());
                }
            }
        }
    }

    /**
     * 新增对象
     *
     * @param dto 保存对象
     * @return String
     */
    @Transactional
    public String saveByAssetId(AssetApplyDTO dto) {
        if (StringUtils.isEmpty(dto.getAssetId())) {
            throw new BusinessException("assetId参数没传入");
        }
        BdpAssetDTO asset = bdpAssetService.selectByPrimaryKey(dto.getAssetId());
        if (asset == null) {
            throw new BusinessException("id=" + dto.getAssetId() + "的资产不存在");
        }

        AssetApplyDTO apply = new AssetApplyDTO();
        apply.setId(ComUtil.getId());
        apply.setAssetId(dto.getAssetId());
        apply.setAssetTitle(asset.getReleaseTitle());
        SysOrg sysOrg = sysOrgUtils.getOrgByUserId(ThreadContextHelper.getUserId());
        apply.setApplyTitle("【" + sysOrg.getOrgName() + "," + ThreadContextHelper.getUserName() + "】" + "申请访问【" + asset.getReleaseTitle() + "】");
        apply.setApplyPerson(ThreadContextHelper.getUserId());
        apply.setApplyTime(new Date());
        apply.setResourceType(Integer.parseInt(asset.getAssetType()));
        apply.setCheckerStatus(CheckerStatus.WAIT_PUBLISH_APPROVE.getCode());
        apply.setApplyServiceType(dto.getApplyServiceType());
        apply.setRemark(dto.getRemark());
        apply.setApplicationId(dto.getApplicationId());
        if (StringUtils.isEmpty(asset.getSecretLevel())) {
            apply.setSecretLevel("1");
        } else {
            apply.setSecretLevel(asset.getSecretLevel());
        }

        PojoUtil.setSysProperties(apply, PlatformConstant.OpType.insert);
        this.insert(apply);

        //启动流程
        ProcessApproveDTO processApproveDTO = new ProcessApproveDTO();
        processApproveDTO.setFlowType(FlowType.APPLY.getCode());
        processApproveDTO.setBusinessId(apply.getId());
        processApproveDTO.setBusinessTitle(apply.getApplyTitle());
        //启动资产发布人所在组织流程
        String result = processApproveService.startProcessTask(processApproveDTO, "bdp_asset_apply", asset.getOrgIdentity());

        // 记录日志
        SysLogUtil.log4Insert(apply);
        return apply.getId();
    }

    /**
     * 新增对象
     *
     * @param dto 保存对象
     * @return String
     */
    @Transactional
    public String save(AssetApplyDTO dto) {
        try {
            dto.setId(ComUtil.getId());
            PojoUtil.setSysProperties(dto, PlatformConstant.OpType.insert);
            this.insert(dto);
            // 记录日志
            SysLogUtil.log4Insert(dto);
            return dto.getId();
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 修改对象部分字段
     *
     * @param dto 修改对象
     * @return int
     */
    @Transactional
    public int update(AssetApplyDTO dto) {
        try {
            int count = this.updateByPrimaryKey(getUpdateDto(dto));
            if (count == 0) {
                throw new DaoException("数据失效，请重新更新");
            }
            return count;
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 通过主键查询单条记录
     *
     * @param id 主键id
     */
    @Transactional(readOnly = true)
    public AssetApplyDTO queryById(String id) {
        try {
            AssetApplyDTO dto = this.selectByPrimaryKey(id);
            // 记录日志
            if (dto != null) {
                SysLogUtil.log4Query(dto);
            }
            return dto;
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 内部方法，获取修改的dto对象
     *
     * @param dto
     * @return
     */
    private AssetApplyDTO getUpdateDto(AssetApplyDTO dto) {
        AssetApplyDTO oldDTO = this.selectByPrimaryKey(dto.getId());
        if (oldDTO == null) {
            throw new DaoException("数据不存在");
        }
        //记录日志
        SysLogUtil.log4Update(dto, oldDTO);
        PojoUtil.setSysProperties(dto, PlatformConstant.OpType.update);
        PojoUtil.copyProperties(oldDTO, dto, true);
        return oldDTO;
    }

    /**
     * 通过审核ID查询
     */
    @Transactional(readOnly = true)
    public AssetApplyDTO queryByApproveId(String approveId) {
        try {
            ProcessApproveDTO processApprove = processApproveService.selectByPrimaryKey(approveId);
            CheckParaUtils.checkDbObjectValidity(processApprove, logger, String.format("没有查到数据，请确保id:%s的审核数据是否存在", approveId));

            AssetApplyDTO dto = this.mapper.selectApply(processApprove.getBusinessId());
            // 记录日志
            if (dto != null) {
                SysLogUtil.log4Query(dto);
            }
            return dto;
        } catch (Exception e) {
            throw new DaoException(e.getMessage(), e);
        }
    }

    public Map<String,String> queryApplyButton(String assetId) {
        Map<String,String> map = new HashMap<>();
        String loginUserId = ThreadContextHelper.getUserId();
        List<AssetApplyDTO> assetApplys = this.mapper.queryApplyButton(assetId,loginUserId);
        BdpAssetDTO bdpAssetDTO = bdpAssetService.selectByPrimaryKey(assetId);
        String openServiceType = bdpAssetDTO.getOpenServiceType();
        List<String> openServiceTypeList = Arrays.asList(openServiceType.split(","));
        if (!"1".equals(bdpAssetDTO.getShareType())) {//如果为不公开并且审核过
            List<String> chenckdList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(assetApplys)){
                for (AssetApplyDTO assetApply : assetApplys) {
                    if (CheckerStatus.APPROVED.getCode() == assetApply.getCheckerStatus() || CheckerStatus.WAIT_PUBLISH_APPROVE.getCode() == assetApply.getCheckerStatus()){
                        List<String> list = Arrays.asList(assetApply.getApplyServiceType().split(","));
                        chenckdList.addAll(list);
                    }
                }
            }

            openServiceTypeList = openServiceTypeList.stream()
                    .filter(element -> !chenckdList.contains(element))
                    .collect(Collectors.toList());
        }
        map.put("queryButton","1");
        map.put("apiButton","1");
        map.put("downloadButton","1");
        map.put("assetId",assetId);
        if (CollectionUtils.isNotEmpty(openServiceTypeList)) {
            if (openServiceTypeList.contains("1")) {
                map.put("queryButton",null);
            }
            if (openServiceTypeList.contains("3")) {
                map.put("apiButton",null);
            }
            if (openServiceTypeList.contains("4")) {
                map.put("downloadButton",null);
            }
        }
        return map;
    }

    public Long getApplyStateByUserId(String createdBy, String assetId, String applicationId) {
        return this.mapper.getApplyStateByUserId(createdBy, assetId, applicationId);
    }
}